// Panneau source d'une citation : extrait exact + contexte voisin, avec contrôle d'accès strict. import { NextResponse } from "next/server"; import { apiError } from "@/lib/api.ts"; import { requireUser } from "@/lib/auth/session.ts"; import { all, get } from "@/lib/db/index.ts"; export async function GET(_req: Request, ctx: { params: Promise<{ chunkId: string }> }) { try { const user = await requireUser(); const id = parseInt((await ctx.params).chunkId, 10); const chunk = get<{ id: number; document_id: number; course_code: string | null; space: string; ref_type: string; ref_number: number | null; ref_label: string; section_title: string; title: string; display_content: string; week: number | null; owner_user_id: number | null; doc_title: string; filename: string; path: string; ingested_at: string | null; }>( `SELECT c.id, c.document_id, c.course_code, c.space, c.ref_type, c.ref_number, c.ref_label, c.section_title, c.title, c.display_content, c.week, c.owner_user_id, d.title as doc_title, d.filename, d.path, d.ingested_at FROM chunks c JOIN documents d ON d.id = c.document_id WHERE c.id = ?`, id ); if (!chunk) return NextResponse.json({ error: "Source introuvable." }, { status: 404 }); // Contrôle d'accès : jamais l'espace professeur pour un étudiant ; les espaces étudiants // uniquement pour leur propriétaire ; les cours officiels selon l'inscription. if (chunk.space === "instructor-private" && user.role === "student") { return NextResponse.json({ error: "Accès refusé." }, { status: 403 }); } if (chunk.space.startsWith("student-") && chunk.owner_user_id !== user.id) { return NextResponse.json({ error: "Accès refusé." }, { status: 403 }); } if (chunk.space.startsWith("official-") && chunk.course_code) { const enrolled = get("SELECT 1 as ok FROM enrollments WHERE user_id = ? AND course_code = ?", user.id, chunk.course_code); if (!enrolled && user.role === "student") return NextResponse.json({ error: "Accès refusé." }, { status: 403 }); } const neighbors = chunk.ref_number != null ? all( `SELECT id, ref_number, title, substr(display_content, 1, 400) as preview FROM chunks WHERE document_id = ? AND ref_number IN (?, ?) AND id != ? ORDER BY ref_number`, chunk.document_id, (chunk.ref_number ?? 0) - 1, (chunk.ref_number ?? 0) + 1, chunk.id ) : []; return NextResponse.json({ source: chunk, neighbors }); } catch (e) { return apiError(e); } }